home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / sgiobj.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  11KB  |  466 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    sgiobj -
  19.  *        A simple object format.
  20.  *
  21.  *            Paul Haeberli - 1990
  22.  */
  23. #include "stdio.h"
  24. #include "gl.h"
  25. #include "device.h"
  26. #include "sgiobj.h"
  27. #include "spin.h"
  28. #include "resource.h"
  29.  
  30. static vertprint();
  31.  
  32. sgiobj *freesgiobj(obj)
  33. sgiobj *obj;
  34. {
  35.     if(obj->data)
  36.     free(obj->data);
  37.     free(obj);
  38. }
  39.  
  40. sgiobj *newquadobj(nquads)
  41. int nquads;
  42. {
  43.     sgiobj *obj;
  44.  
  45.     obj = (sgiobj *)mymalloc(sizeof(sgiobj));
  46.     obj->next = 0;
  47.     obj->objtype = OBJ_QUADLIST;
  48.     obj->nlongs = PNTLONGS*4*nquads;
  49.     obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
  50.     obj->xnlongs = 0;
  51.     obj->xdata = 0;
  52.     return obj;
  53. }
  54.  
  55. sgiobj *newtriobj(ntri)
  56. int ntri;
  57. {
  58.     sgiobj *obj;
  59.  
  60.     obj = (sgiobj *)mymalloc(sizeof(sgiobj));
  61.     obj->next = 0;
  62.     obj->objtype = OBJ_TRILIST;
  63.     obj->nlongs = PNTLONGS*3*ntri;
  64.     obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
  65.     obj->xnlongs = 0;
  66.     obj->xdata = 0;
  67.     return obj;
  68. }
  69.  
  70. sgiobj *newtmeshobj(nlongs)
  71. int nlongs;
  72. {
  73.     sgiobj *obj;
  74.  
  75.     obj = (sgiobj *)mymalloc(sizeof(sgiobj));
  76.     obj->next = 0;
  77.     obj->objtype = OBJ_TRIMESH;
  78.     obj->nlongs = nlongs;
  79.     obj->data = (long *)mymalloc(obj->nlongs*sizeof(long));
  80.     obj->xnlongs = 0;
  81.     obj->xdata = 0;
  82.     return obj;
  83. }
  84.  
  85. sgiobj *clonesgiobj(obj)
  86. sgiobj *obj;
  87. {
  88.     sgiobj *cobj;
  89.     int nlongs;
  90.  
  91.     cobj = (sgiobj *)mymalloc(sizeof(sgiobj));
  92.     *cobj = *obj;
  93.     cobj->data = (long *)mymalloc(cobj->nlongs*sizeof(int));
  94.     bcopy(obj->data,cobj->data,cobj->nlongs*sizeof(int));
  95.     if(cobj->xnlongs) {
  96.     cobj->xdata = (long *)mymalloc(cobj->xnlongs*sizeof(int));
  97.     bcopy(obj->xdata,cobj->xdata,cobj->xnlongs*sizeof(int));
  98.     }
  99.     return cobj;
  100. }
  101.  
  102. sgiobj *readsgiobj(name)
  103. char *name;
  104. {
  105.     FILE *inf;
  106.     sgiobj *obj, *head, *tail;
  107.     int npoints, colors;
  108.     long objtype, plongs, nlongs;
  109.     long magic;
  110.     int i, ntri, nquads;
  111.  
  112.     inf = res_fopen(name,"r");
  113.     if(!inf) {
  114.         fprintf(stderr,"readsgiobj: can't open input file %s\n",name);
  115.         exit(1);
  116.     }
  117.     res_fread(&magic,sizeof(long),1,inf);
  118.     if(magic == FASTMAGIC) {
  119.     res_fread(&npoints,sizeof(long),1,inf);
  120.     res_fread(&colors,sizeof(long),1,inf);
  121.     nquads = npoints/4; 
  122.     if(colors) {
  123.         fprintf(stderr,"readsgiobj: can't read nonormal spin objects\n");
  124.         exit(1);
  125.     } else
  126.         obj = newquadobj(nquads);
  127.     bzero(obj->data,obj->nlongs*sizeof(long));
  128.     for(i=0; i<npoints; i++) {
  129.         res_fread(obj->data+(PNTLONGS*i)+OFFSET_NORMAL,3*sizeof(long),1,inf);
  130.         res_fread(obj->data+(PNTLONGS*i)+OFFSET_POINT,3*sizeof(long),1,inf);
  131.         bcopy(obj->data+(PNTLONGS*i)+OFFSET_POINT,
  132.           obj->data+(PNTLONGS*i)+OFFSET_UVS,3*sizeof(long),1,inf);
  133.     }
  134.     res_fclose(inf);
  135.     return obj;
  136.     } 
  137.     if(magic == SOMAGIC) {
  138.     head = 0;
  139.     while(1) {
  140.         res_fread(&objtype,sizeof(long),1,inf);
  141.         if(objtype == OBJ_END)
  142.         break;
  143.         res_fread(&nlongs,sizeof(long),1,inf);
  144.         switch(objtype) {
  145.         case OBJ_QUADLIST:
  146.             nquads = (nlongs/PNTLONGS)/4;
  147.             obj  = newquadobj(nquads);
  148.             res_fread(obj->data,nlongs*sizeof(long),1,inf);
  149.             break;
  150.         case OBJ_TRILIST:
  151.             ntri = (nlongs/PNTLONGS)/3;
  152.             obj  = newtriobj(ntri);
  153.             res_fread(obj->data,nlongs*sizeof(long),1,inf);
  154.             break;
  155.         case OBJ_TRIMESH:
  156.             obj = newtmeshobj(nlongs);
  157.             res_fread(obj->data,nlongs*sizeof(long),1,inf);
  158.             break;
  159.         default:
  160.             fprintf(stderr,"readsgiobj: bad obj type %d\n",objtype);
  161.             exit(1);
  162.             break;
  163.         }
  164.         if(head == 0) {
  165.         head = tail = obj;
  166.         } else {
  167.         tail->next = obj;
  168.         tail = obj;
  169.         }
  170.     }
  171.     res_fclose(inf);
  172.     return head;
  173.     }
  174.     fprintf(stderr,"readsgiobj: bad magic %d in object file\n",magic);
  175.     exit(1);
  176. }
  177.  
  178. writesgiobj(name,obj)
  179. char *name;
  180. sgiobj *obj;
  181. {
  182.     FILE *outf;
  183.     long endtype; 
  184.     int magic;
  185.  
  186.     outf = fopen(name,"w");
  187.     if(!outf) {
  188.         fprintf(stderr,"writesgiobj: can't open input file %s\n",name);
  189.         exit(1);
  190.     }
  191.     magic = SOMAGIC;
  192.     fwrite(&magic,sizeof(long),1,outf);
  193.     while(obj) {
  194.     fwrite(&obj->objtype,sizeof(long),1,outf);
  195.     fwrite(&obj->nlongs,sizeof(long),1,outf);
  196.     fwrite(obj->data,obj->nlongs*sizeof(long),1,outf);
  197.     obj = obj->next;
  198.     }
  199.     endtype = OBJ_END;
  200.     fwrite(&endtype,sizeof(long),1,outf);
  201.     fclose(outf);
  202. }
  203.  
  204. applytoverts(obj,func)
  205. sgiobj *obj;
  206. int (*func)();
  207. {
  208.     long npolys, nverts;
  209.     long *data;
  210.     char *vertdata, *avert;
  211.  
  212.     data = obj->data;
  213.     if(obj->objtype == OBJ_QUADLIST) {
  214.     npolys = (obj->nlongs/PNTLONGS)/4;
  215.     while(npolys--) {
  216.         func(&data[(PNTLONGS*0)]);
  217.         func(&data[(PNTLONGS*1)]);
  218.         func(&data[(PNTLONGS*2)]);
  219.         func(&data[(PNTLONGS*3)]);
  220.         data += PNTLONGS*4;
  221.     }
  222.     } else if(obj->objtype == OBJ_TRILIST) {
  223.     npolys = (obj->nlongs/PNTLONGS)/3;
  224.     while(npolys--) {
  225.         func(&data[(PNTLONGS*0)]);
  226.         func(&data[(PNTLONGS*1)]);
  227.         func(&data[(PNTLONGS*2)]);
  228.         data += PNTLONGS*3;
  229.     }
  230.     } else if(obj->objtype == OBJ_TRIMESH) {
  231.     nverts = (*data++)/PNTLONGS;
  232.     while(nverts--) {
  233.         func(data);
  234.         data += PNTLONGS;
  235.     }
  236.     } else {
  237.     fprintf(stderr,"applytoverts: bad object type %d\n",obj->objtype);
  238.     exit(1);
  239.     }
  240. }
  241.  
  242. /*
  243.  *    count triangles in an sgi object.
  244.  *
  245.  *
  246.  */
  247. static int tricount;
  248.  
  249. static int pcount()
  250. {
  251.     tricount++;
  252. }
  253.  
  254. objpolys(obj)
  255. sgiobj *obj;
  256. {
  257.     tricount=0;
  258.     applytotris(obj,pcount);
  259.     return tricount;
  260. }
  261.  
  262. applytomeshtris(obj,trifunc)
  263. sgiobj *obj;
  264. int (*trifunc)();
  265. {
  266.     long *data;
  267.     char *vertdata, *avert;
  268.     int vertlongs, nverts;
  269.  
  270.     if(obj->objtype != OBJ_TRIMESH) {
  271.     fprintf(stderr,"applytomeshtris: object type is not a tmesh\n");
  272.     exit(1);
  273.     }
  274.     data = obj->data;
  275.     vertlongs = *data++;
  276.     vertdata = (char *)data;
  277.     data += vertlongs;
  278.     mesh_callback(trifunc);
  279.     while(1) {
  280.     switch(*data++) {
  281.         case OP_BGNTMESH:
  282.         mesh_bgntmesh();
  283.         break;
  284.         case OP_SWAPTMESH:
  285.         mesh_swaptmesh();
  286.         break;
  287.         case OP_ENDBGNTMESH:
  288.         mesh_endtmesh();
  289.         mesh_bgntmesh();
  290.         break;
  291.         case OP_ENDTMESH:
  292.         mesh_endtmesh();
  293.         return;
  294.         default:
  295.         fprintf(stderr,"applytomeshtris: bad tmesh op %d\n",*data);
  296.         exit(1);
  297.     }
  298.     nverts = *data++;
  299.     while(nverts--) {
  300.         avert = vertdata + *data++;
  301.         mesh_vert(avert);
  302.     }
  303.     }
  304. }
  305.  
  306. static int (*usertrifunc)();
  307.  
  308. static mymeshtrifunc(data)
  309. long *data[3];
  310. {
  311.     (usertrifunc)(data[0],data[1],data[2]);
  312. }
  313.  
  314. applytotris(obj,func)
  315. sgiobj *obj;
  316. int (*func)();
  317. {
  318.     long npolys;
  319.     long *data;
  320.     char *vertdata, *avert;
  321.     int nverts;
  322.  
  323.     data = obj->data;
  324.     if(obj->objtype == OBJ_QUADLIST) {
  325.     npolys = (obj->nlongs/PNTLONGS)/4;
  326.     while(npolys--) {
  327.         func(&data[(PNTLONGS*0)],
  328.          &data[(PNTLONGS*1)],
  329.          &data[(PNTLONGS*3)]);
  330.         func(&data[(PNTLONGS*2)],
  331.          &data[(PNTLONGS*3)],
  332.          &data[(PNTLONGS*1)]);
  333.         data += PNTLONGS*4;
  334.     }
  335.     } else if(obj->objtype == OBJ_TRILIST) {
  336.     npolys = (obj->nlongs/PNTLONGS)/3;
  337.     while(npolys--) {
  338.         func(&data[(PNTLONGS*0)],
  339.          &data[(PNTLONGS*1)],
  340.          &data[(PNTLONGS*2)]);
  341.         data += PNTLONGS*3;
  342.     }
  343.     } else if(obj->objtype == OBJ_TRIMESH) {
  344.     usertrifunc = func;
  345.     applytomeshtris(obj,mymeshtrifunc);
  346.     } else {
  347.     fprintf(stderr,"applytotris: bad object type %d\n",obj->objtype);
  348.     exit(1);
  349.     }
  350. }
  351.  
  352. sgiobj *catsgiobj(obj1,obj2)
  353. sgiobj *obj1, *obj2;
  354. {
  355.     sgiobj *obj;
  356.     long *data;
  357.     long npolys1, npolys2;
  358.  
  359.     if(obj1->objtype != obj2->objtype) {
  360.     fprintf(stderr,"catsgiobj: both objects must have the same type\n");
  361.     exit(1);
  362.     }
  363.     if(obj1->objtype == OBJ_QUADLIST) {
  364.     npolys1 = (obj1->nlongs/PNTLONGS)/4;
  365.     npolys2 = (obj2->nlongs/PNTLONGS)/4;
  366.     obj = newquadobj(npolys1+npolys2);
  367.     data = obj->data;
  368.     bcopy(obj1->data,data,obj1->nlongs*sizeof(long));
  369.     data += obj1->nlongs;
  370.     bcopy(obj2->data,data,obj2->nlongs*sizeof(long));
  371.     return obj;
  372.     } else if(obj1->objtype == OBJ_TRILIST) {
  373.     npolys1 = (obj1->nlongs/PNTLONGS)/3;
  374.     npolys2 = (obj2->nlongs/PNTLONGS)/3;
  375.     obj = newtriobj(npolys1+npolys2);
  376.     data = obj->data;
  377.     bcopy(obj1->data,data,obj1->nlongs*sizeof(long));
  378.     data += obj1->nlongs;
  379.     bcopy(obj2->data,data,obj2->nlongs*sizeof(long));
  380.     return obj;
  381.     } else if(obj->objtype == OBJ_TRIMESH) {
  382.     fprintf(stderr,"catsgiobj: tmesh not implemented\n");
  383.     exit(1);
  384.     } else {
  385.     fprintf(stderr,"catsgiobj: bad object type %d\n",obj->objtype);
  386.     exit(1);
  387.     }
  388. }
  389.  
  390. printsgiobj(obj,how)
  391. sgiobj *obj;
  392. int how;
  393. {
  394.     long npolys;
  395.     long *data;
  396.     char *vertdata, *avert;
  397.     int vertlongs, nverts;
  398.  
  399.     data = obj->data;
  400.     if(obj->objtype == OBJ_QUADLIST) {
  401.     npolys = (obj->nlongs/PNTLONGS)/4;
  402.     while(npolys--) {
  403.         printf("QUAD:\n");
  404.         vertprint(&data[PNTLONGS*0]);
  405.         vertprint(&data[PNTLONGS*1]);
  406.         vertprint(&data[PNTLONGS*2]);
  407.         vertprint(&data[PNTLONGS*3]);
  408.         data += PNTLONGS*4;
  409.     }
  410.     } else if(obj->objtype == OBJ_TRILIST) {
  411.     npolys = (obj->nlongs/PNTLONGS)/3;
  412.     while(npolys--) {
  413.         printf("TRI:\n");
  414.         vertprint(&data[PNTLONGS*0]);
  415.         vertprint(&data[PNTLONGS*1]);
  416.         vertprint(&data[PNTLONGS*2]);
  417.         data += PNTLONGS*3;
  418.     }
  419.     } else if(obj->objtype == OBJ_TRIMESH) {
  420.     vertlongs = *data++;
  421.     printf("vertlongs is %d\n",vertlongs);
  422.     vertdata = (char *)data;
  423.     data += vertlongs;
  424.     printf("TMESH:\n");
  425.     while(1) {
  426.         switch(*data++) {
  427.         case OP_BGNTMESH:
  428.             printf("bgntmesh\n");
  429.             break;
  430.         case OP_SWAPTMESH:
  431.             printf("swaptmesh\n");
  432.             break;
  433.         case OP_ENDBGNTMESH:
  434.             printf("endbgntmesh\n");
  435.             break;
  436.         case OP_ENDTMESH:
  437.             printf("endtmesh\n");
  438.             return;
  439.         default:
  440.             fprintf(stderr,"printsgiobj: bad tmesh op %d\n",*data);
  441.             exit(1);
  442.         }
  443.         nverts = *data++;
  444.         while(nverts--) {
  445.         avert = vertdata + *data++;
  446.         vertprint(avert);
  447.         }
  448.     }
  449.     } else {
  450.     fprintf(stderr,"printsgiobj: bad object type %d\n",obj->objtype);
  451.     exit(1);
  452.     }
  453. }
  454.  
  455. static vertprint(fptr)
  456. float *fptr;
  457. {
  458.     printf("pos: %f %f %f\n",
  459.          fptr[OFFSET_POINT+0],fptr[OFFSET_POINT+1],fptr[OFFSET_POINT+2]);
  460.     printf("norm: %f %f %f\n",
  461.          fptr[OFFSET_NORMAL+0],fptr[OFFSET_NORMAL+1],fptr[OFFSET_NORMAL+2]);
  462.     printf("uvs: %f %f %f\n",
  463.          fptr[OFFSET_UVS+0],fptr[OFFSET_UVS+1],fptr[OFFSET_UVS+2]);
  464.     printf("\n");
  465. }
  466.